import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * CyclicBarrier (循环屏障) 示例代码
 * 模拟场景：集齐七颗龙珠，召唤神龙。
 */
public class CyclicBarrierDemo {
    public static void main(String[] args) {
        // 创建一个 CyclicBarrier 实例。
        // 参数 7 表示需要 7 个线程都到达这个屏障点（集合点）。
        // 第二个参数是一个 Runnable 任务（也叫“屏障操作”），
        // 当 7 个线程都到达后，会由最后一个到达的线程优先执行这个任务。
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
            System.out.println("----集齐七颗龙珠，成功召唤神龙！");
        });

        // 创建 7 个线程，模拟去收集 7 颗龙珠的过程。
        for (int i = 1; i <= 7; i++) {
            // 因为 i 是循环变量，在 Lambda 表达式中必须是 final 或事实上的 final。
            // 所以创建一个临时变量 finalI 来捕获每次循环中 i 的值。
            final int finalI = i;

            // 创建并启动线程，并为每个线程命名，方便观察。
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t" + "收集到第 " + finalI + " 颗龙珠");

                try {
                    // 每个线程完成自己的任务后，调用 await() 方法。
                    // 这表示当前线程已经到达了屏障（集合点），并开始等待其他线程。
                    // 在所有 7 个线程都调用 await() 之前，它们都会在这里被阻塞。
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    // 在等待过程中，如果其他线程中断了当前线程，会抛出此异常。
                    throw new RuntimeException(e);
                } catch (BrokenBarrierException e) {
                    // 如果有线程在等待过程中被中断、超时，或者屏障被重置(reset)，
                    // 那么所有其他正在等待的线程都会抛出此异常，表示屏障被打破了。
                    throw new RuntimeException(e);
                }
            }, "收集者-" + i).start();
        }
    }
}